extends Node2D

@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var balance: Sprite2D = $Balance
@onready var coins: Array[Coin] = [$CoinContainer/Coin1, $CoinContainer/Coin2, $CoinContainer/Coin3, $CoinContainer/Coin4, $CoinContainer/Coin5, $CoinContainer/Coin6, $CoinContainer/Coin7, $CoinContainer/Coin8, $CoinContainer/Coin9, $CoinContainer/Coin10, $CoinContainer/Coin11, $CoinContainer/Coin12]
@onready var first: Button = $HistoryContainer/First
@onready var second: Button = $HistoryContainer/Second
@onready var third: Button = $HistoryContainer/Third
@onready var contestant_mode: Button = $ModeContainer/ContestantMode
@onready var quizmaster_mode: Button = $ModeContainer/QuizmasterMode
@onready var left_weigh_coins: WeighCoins = $LeftWeighContainer/LeftWeighCoins
@onready var right_weigh_coins: WeighCoins = $RightWeighContainer/RightWeighCoins
const COLOR_OVERLAY: PackedScene           = preload("res://core/components/color_overlay.tscn")
var coin_selected: Array[bool]    = [false, false, false, false, false, false, false, false, false, false, false, false]
var coin_value: Array[int]        = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
var left_coins: Array[int]        = []
var left_coins_index: Array[int]  = []
var right_coins: Array[int]       = []
var right_coins_index: Array[int] = []
var left_count: int               = 3
var history: Array                = []


func _ready():
	contestant_mode.disabled = true
	_signal_connect()
	restart_game()
	_mode_check()
	show_puzzle_info()


func _signal_connect():
	for coin in coins:
		coin.coin_selected.connect(_on_coin_selected_changed)


func _mode_check() -> void:
	var puzzle_solved = GameData.puzzle_solved.get("fake_coin", false)
	if puzzle_solved:
		quizmaster_mode.disabled = false
		quizmaster_mode.tooltip_text = ""

	else:
		quizmaster_mode.disabled = true
		quizmaster_mode.tooltip_text = tr("m.unlock")


func _on_coin_selected_changed(coin_index: int, selected: bool):
	coin_selected[coin_index] = selected


func _reset_coin_selected():
	coin_selected = [false, false, false, false, false, false, false, false, false, false, false, false]


func _reset_left_count():
	left_count = 3


func _reset_coins(activate: bool = true):
	for i in range(coins.size()):
		if activate:
			coins[i].activate()
		else:
			coins[i].deactivate()
		coins[i].button_pressed = false
		coins[i].modulate = Color.WHITE


func _random_coin_value():
	# 首先重置coin_value
	for i in range(coins.size()):
		coin_value[i] = 0
	# 从27种可能性中选择一种, 应用到coin_value中
	var random_value: int = randi_range(1, 25)
	if random_value >= 1 and random_value <= 12:
		var index: int = random_value - 1
		coin_value[index] = 1
	elif random_value >= 13 and random_value <= 24:
		var index: int = random_value - 13
		coin_value[index] = -1



func _on_place_left_pressed() -> void:
	for i in range(coin_selected.size()):
		if coin_selected[i] == true:
			left_coins.append(coin_value[i] + 10)
			left_coins_index.append(i)
			left_weigh_coins.add_coins(1, Color(0.2, 0.8, 0.2))
			coins[i].deactivate()
			# 偏绿
			coins[i].modulate = Color(0.2, 0.8, 0.2, 0.5)
			coins[i].button_pressed = false

	_reset_coin_selected()


func _on_place_right_pressed() -> void:
	for i in range(coin_selected.size()):
		if coin_selected[i] == true:
			right_coins.append(coin_value[i] + 10)
			right_coins_index.append(i)
			right_weigh_coins.add_coins(1, Color(1, 0.5, 0.5))
			coins[i].deactivate()
			# 偏红
			coins[i].modulate = Color(1, 0.5, 0.5, 0.5)
			coins[i].button_pressed = false

	_reset_coin_selected()


func _on_reset_pressed() -> void:
	_reset_weigh()
	$OperationContainer/PlaceLeft.disabled = false
	$OperationContainer/PlaceRight.disabled = false
	$OperationContainer/StartWeighing.disabled = false


func _reset_weigh() -> void:
	left_coins = []
	left_coins_index = []
	right_coins    =  []
	right_coins_index = []
	_reset_coin_selected()
	_reset_coins()
	left_weigh_coins.clear_coins()
	right_weigh_coins.clear_coins()
	animation_player.play("RESET")


func _on_start_weighing_pressed() -> void:
	left_count -= 1
	# 计算左右两边的重量,确定天平是否倾斜

	var left_weight: int  = 0
	var right_weight: int = 0

	# 计算左侧硬币总重量
	for weight in left_coins:
		left_weight += weight

	# 计算右侧硬币总重量
	for weight in right_coins:
		right_weight += weight

	# 根据重量比较播放不同的动画
	if left_weight > right_weight:
		animation_player.play("left")
	elif right_weight > left_weight:
		animation_player.play("right")
	else:
		animation_player.play("idle")

	var result: Dictionary = {
								 "left_coins": left_coins,
								 "right_coins": right_coins,
								 "left_weight": left_weight,
								 "right_weight": right_weight,
								 "left_coins_index": left_coins_index,
								 "right_coins_index": right_coins_index
							 }
	history.append(result)

	if history.size() == 1:
		first.visible = true

	if history.size() == 2:
		second.visible = true

	if history.size() == 3:
		third.visible = true


func _weigh_end() -> void:
	_reset_weigh()
	left_weigh_coins.clear_coins()
	right_weigh_coins.clear_coins()
	if left_count > 0:
		return
	for i in range(coins.size()):
		coins[i].deactivate()
		coins[i].button_pressed = false
	$OperationContainer/PlaceLeft.visible = false
	$OperationContainer/PlaceRight.visible = false
	$OperationContainer/Reset.visible = false
	$OperationContainer/StartWeighing.visible = false


func _on_first_pressed() -> void:
	show_histroy(0)


func _on_second_pressed() -> void:
	show_histroy(1)


func _on_third_pressed() -> void:
	show_histroy(2)


func show_histroy(index: int) -> void:
	if left_count > 0:
		_reset_weigh()

	_reset_coins(false)
	left_weigh_coins.clear_coins()
	right_weigh_coins.clear_coins()

	$OperationContainer/PlaceLeft.disabled = true
	$OperationContainer/PlaceRight.disabled = true
	$OperationContainer/StartWeighing.disabled = true

	var hist         = history[index]
	var _left_index  = hist.get("left_coins_index")
	var _right_index = hist.get("right_coins_index")
	for l_i in _left_index:
		# 偏绿
		coins[l_i].modulate = Color(0.2, 0.8, 0.2, 0.5)
		left_weigh_coins.add_coins(1, Color(0.2, 0.8, 0.2))

	for r_i in _right_index:
		# 偏红
		coins[r_i].modulate = Color(0.8, 0.2, 0.2, 0.5)
		right_weigh_coins.add_coins(1, Color(0.8, 0.2, 0.2))

	var _left_weight  = hist.get("left_weight")
	var _right_weight = hist.get("right_weight")
	if _left_weight > _right_weight:
		# 切换到left动画, 并停留在第1.1秒
		animation_player.play("left")
		animation_player.seek(1.1, true)  # 跳转到第1秒
		animation_player.pause()
		$OperationContainer/Reset.disabled = false

	elif _right_weight > _left_weight:
		# 切换到right动画, 并停留在第1.1秒
		animation_player.play("right")
		animation_player.seek(1.1, true)  # 跳转到第1秒
		animation_player.pause()
		$OperationContainer/Reset.disabled = false

	else:
		# 切换到idle动画, 并停留在第0.5秒
		animation_player.play("idle")
		animation_player.seek(0.5, true)
		animation_player.pause()
		$OperationContainer/Reset.disabled = false


func _on_option_button_item_selected(_index: int) -> void:
	$ResultContainer/HasFakeCoin.button_pressed = true


func _on_confirm_pressed() -> void:
	var _has_fake_coin = $ResultContainer/HasFakeCoin.button_pressed
	if not _has_fake_coin:
		if coin_value.all(func (coin) -> bool: return coin == 0):
			_puzzle_solved()
			return
		else:
			_wrong_answer()
			return

	var _fake_coin_index = $ResultContainer/CoinOptionButton.selected
	var weight_option    = $ResultContainer/WeightOptionButton.selected * 2 - 1

	if coin_value[_fake_coin_index] == weight_option:
		_puzzle_solved()
	else:
		_wrong_answer()


func _puzzle_solved() -> void:
	GameManager.set_puzzle_solved(true, "fake_coin")
	GameManager.save_game()

	# 创建遮罩层
	var overlay: ColorOverlay = COLOR_OVERLAY.instantiate()
	add_child(overlay)

	overlay.set_title(tr("m.congratulations"))
	overlay.set_label(tr("m.solved"))

	# 创建返回主菜单按钮
	var menu_button = Button.new()
	menu_button.text = tr("m.back_to_menu")
	menu_button.size = Vector2(120, 40)
	
	# 连接按钮点击事件
	menu_button.connect("pressed", func():
		overlay.queue_free()  # 移除遮罩层
		GameManager.back_to_main_menu()  # 返回主菜单
	)


	overlay.operation_container.add_child(menu_button)



func _wrong_answer() -> void:
	# 创建遮罩层
	var overlay: ColorOverlay = COLOR_OVERLAY.instantiate()
	add_child(overlay)

	# 查找假币的索引和重量信息
	var fake_coin_index: int = -1
	var is_heavy: bool       = true
	for i in range(coin_value.size()):
		if coin_value[i] != 0:
			fake_coin_index = i
			is_heavy = coin_value[i] > 0
			break

	overlay.set_title(tr("m.wrong"))
	# 设置提示文本
	if fake_coin_index != -1:
		var coin_number: int    = fake_coin_index + 1
		var weight_text: String = tr("fc.heavier") if is_heavy else tr("fc.lighter")
		overlay.set_label(tr("fc.correct_answer_fake_coin_info") % [coin_number, weight_text])
	else:
		overlay.set_label(tr("fc.all_coins_are_real"))

	# 创建确认按钮
	var confirm_button = Button.new()
	confirm_button.text = tr("m.restart")

	confirm_button.position = Vector2(250, 140)
	confirm_button.size = Vector2(100, 40)

	# 连接按钮点击事件
	confirm_button.connect("pressed", func():
		overlay.queue_free()  # 移除遮罩层
		restart_game()        # 重启游戏
	)
	overlay.operation_container.add_child(confirm_button)




func restart_game() -> void:
	# 重置游戏状态
	_reset_weigh()
	_reset_coins(true)
	_reset_coin_selected()
	_reset_left_count()

	# 清空历史记录
	history.clear()

	# 隐藏历史按钮
	first.visible = false
	second.visible = false
	third.visible = false

	# 显示操作按钮
	$OperationContainer/PlaceLeft.visible = true
	$OperationContainer/PlaceRight.visible = true
	$OperationContainer/Reset.visible = true
	$OperationContainer/StartWeighing.visible = true

	# 启用操作按钮
	$OperationContainer/PlaceLeft.disabled = false
	$OperationContainer/PlaceRight.disabled = false
	$OperationContainer/StartWeighing.disabled = false
	$OperationContainer/Reset.disabled = false

	# 重新生成假币
	_random_coin_value()

	# 重置结果选择
	$ResultContainer/HasFakeCoin.button_pressed = false
	$ResultContainer/NoFakeCoin.button_pressed = true
	$ResultContainer/CoinOptionButton.selected = 0
	$ResultContainer/WeightOptionButton.selected = 0

	# 重置动画
	animation_player.play("RESET")


func _on_back_to_menu_pressed() -> void:
	GameManager.back_to_main_menu()


func _on_puzzle_info_pressed() -> void:
	show_puzzle_info()
	
	
func show_puzzle_info() -> void:
	var overlay: ColorOverlay = COLOR_OVERLAY.instantiate()
	
	add_child(overlay)
	
	overlay.set_title(tr("fc.fake_coin_puzzle"))
	overlay.set_label(tr("fc.fake_coin_puzzle_info"))
	var confirm_button: Button = Button.new()
	confirm_button.text = tr("m.confirm")
	confirm_button.connect("pressed", overlay.queue_free)
	
	overlay.operation_container.add_child(confirm_button)

func _on_quizmaster_mode_pressed() -> void:
	get_tree().change_scene_to_file("res://core/puzzles/fake_coin/quizmaster.tscn")
